iT邦幫忙

2022 iThome 鐵人賽

DAY 29
0

快到鐵人賽尾聲了,這幾天找資料時發現這個沒提過的概念 - Utility Types,就讓我們來看一下這是什麼吧。

(這邊跟React沒有直接關係,你可以使用TypeScript遊樂場來實做看看,滿好玩的!)

簡單來說,Utility Types可以讓你用既有的型別、去創造出另一個型別。具體的實作方法,跟一般的函式很類似,我們接收一個"型別"當作input,最後以另外一個型別當成output輸出。之所以會有這個概念,是因為要輸出的型別,多少跟當作輸入的型別有一點關係,如果我們必須再次手動攥寫出一個類似型別,有點..失去了程式語言的初衷。目前官方提供的Utility Types多達22種,隨著版本的更新,仍在持續增加中。金天我們就來看幾個簡單、比較易用的吧!

Partial<Type>

Partial可以使我們所帶入的型別,其內部原本為必須的型別,通通都變成選擇性的。
假設我們有個Player球員型別,所有的球員本來都必須有姓名、年紀、能力指標,而後來因各種因素,內部資訊已經不需要了,你就能將原本設定好的Player型別,對他使用Partial,產生出一個全部都選擇性的型別。

    type Player = {
        name:string,
        age:number,
        ability:"Great" | "Average" | "Meh"
    }
    
    type NewPlayer = Partial<Player>
    
    //a.k.a.
    
    type NewPlayer = {
        name?: string | undefined;
        age?: number | undefined;
        ability?: "Great" | "Average" | "Meh" | undefined;
    } 
    

Required<Type>

既然Partial是將原本必須的型別改為選擇性,Required顧名思義就是相反的概念,將原本是選擇性的型別,改變成為必須的。

    type Player = {
        name: string,
        age?: number,
        ability?: "Great" | "Average" | "Meh"
    }
    
    type NewPlayer = Required<Player>
    
    //a.k.a
    
    type LittlePlayer = {
        name: string;
        age: number;
        ability: "Great" | "Average" | "Meh";
}

Pick<Type, Keys>

Pick,翻成中文就是挑選嘛,我們會從要輸入的型別當中,挑選出我們想要的"鍵"(Keys),並產出一個新的型別。

    type Player = {
      name: string,
      age?: number,
      ability?: "Great" | "Average" | "Meh"
    }

    //這邊我還滿意外的,我以為要挑"A跟B",應該要是"&"這個符號
    //沒想到在TypeScript內得用"|"這個符號
    //但如果在JavaScript當中,我們可能會將"|"聯想到or去(還是只有我這樣?)
    type NewPlayer = Pick<Player, "name" | "age">
    
    //a.k.a.
    //你會發現,就連age的選擇性也被選過來了
    //所以我們要是後續有變動Player型別,NewPlayer就會跟著變動,很方便
    type NewPlayer = {
        name: string;
        age?: number | undefined;
    }

Readonly<Type>

這個應該也是看名字就很好懂的,我們將Type輸入進Readonly,就能得到一個,內部所有屬性都不可再賦值的物件。

    type Player = {
      name: string
      age: number
      ability: "Great" | "Average" | "Meh"
    }

    const FrozenPlayer: Readonly<Player> = {
      name: "John",
      age: 18,
      ability: "Great"
    }
    //下面這行就會出錯
    //因為 'name' 為唯讀屬性,所以無法指派至 'name'。
    FrozenPlayer.name = "Allen"

Omit<Type, Keys>

Omit,就是"遺漏;省略;刪去"。我們上面看過這麼多例子了,想必你一定也能猜出這在幹嘛。
我們選定一個Type,將內部其中一個(或多個鍵)給去除掉後,把剩下來的鍵值對當作新的型別來使用。

    type Player = {
      name: string
      age: number
      ability: "Great" | "Average" | "Meh"
    }
    
    //我們不管能力,球員會動就好
    
    const RandomPlayer: Omit<Player, "ability"> = {
      name: "John",
      age: 20
    }
    
    //你若硬是要為RandomPlayer寫入ability,則會報錯!
    //跟剛剛Pick的例子一樣,你要一次omit多個key,則用"|"寫入即可

小結

TypeScript所提供的Utility Types有二十多個,我們不會、也沒必要在這邊看完,但你必須知道有這些東西的存在,日後回想起來、或者讀其他codebase時,不要被這些看似陌生的"型別"給嚇到,這篇文章的目的就達到了!

那我們最後一天再見!


上一篇
第28天!function/arrow function component與泛型組合技練習!
下一篇
第30天! TypeScript後續學習管道!
系列文
你也對開始使用typescript感到無力嗎?我也是 - 30天初探typescript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言